import re
from typing import List, Dict, Any, Callable, Optional
from datetime import datetime

from src.models.base import CourseContent, CourseChapter, CoursePoint, ProcessStep
from src.utils.logger import get_logger

logger = get_logger(__name__)


class StepwiseCourseParser:
    """分步骤的课程内容解析器."""
    
    STEPS = [
        "file_parsing",      # 文件解析
        "content_analysis",  # 内容分析
        "chapter_generation", # 章节生成
        "points_generation", # 要点生成  
        "result_assembly"    # 结果组装
    ]
    
    def __init__(self):
        self.chapter_keywords = [
            "章节", "章", "第一章", "第二章", "第三章", "第四章", "第五章",
            "单元", "模块", "部分", "lesson", "chapter", "unit", "module"
        ]
        self.point_keywords = [
            "要点", "重点", "核心", "关键", "主要内容", "学习目标",
            "知识点", "技能点", "point", "key", "important"
        ]
        
        # 处理回调
        self.progress_callback: Optional[Callable] = None
        self.current_step = 0
        self.parsed_content = ""
        self.course_title = ""
        self.chapters = []
    
    def set_progress_callback(self, callback: Callable):
        """设置进度回调函数."""
        self.progress_callback = callback
    
    def _update_progress(self, step_name: str, status: str, progress: int, message: str, details: Dict[str, Any] = None):
        """更新进度."""
        if self.progress_callback:
            self.progress_callback(step_name, status, progress, message, details)
    
    async def parse_from_file(self, file_path: str, file_type: str) -> CourseContent:
        """从文件解析课程内容."""
        try:
            # 步骤1: 文件解析
            self._update_progress("file_parsing", "processing", 0, f"正在解析{file_type}文件")
            
            from src.utils.file_parser import FileParser
            file_parser = FileParser()
            
            content = await file_parser.parse_file(file_path, file_type)
            if not content:
                raise ValueError("文件解析失败或内容为空")
            
            self._update_progress("file_parsing", "completed", 100, 
                                f"文件解析完成，提取文本长度: {len(content)}字符",
                                {"extracted_length": len(content), "file_type": file_type})
            
            return await self.parse_from_content(content)
            
        except Exception as e:
            self._update_progress("file_parsing", "failed", 0, f"文件解析失败: {str(e)}")
            raise
    
    async def parse_from_content(self, content: str) -> CourseContent:
        """从文本内容解析课程内容."""
        try:
            # 步骤2: 内容分析
            self._update_progress("content_analysis", "processing", 0, "正在分析课程内容结构")
            
            self.parsed_content = self._preprocess_content(content)
            self.course_title = self._extract_course_title(self.parsed_content)
            
            # 分析内容特征
            lines = self.parsed_content.split('\n')
            total_lines = len([line for line in lines if line.strip()])
            
            self._update_progress("content_analysis", "completed", 100, 
                                "内容分析完成", 
                                {
                                    "course_title": self.course_title,
                                    "total_lines": total_lines,
                                    "content_length": len(self.parsed_content)
                                })
            
            # 步骤3: 章节生成
            self._update_progress("chapter_generation", "processing", 0, "正在识别和生成课程章节")
            
            self.chapters = await self._generate_chapters(self.parsed_content)
            
            self._update_progress("chapter_generation", "completed", 100,
                                f"章节生成完成，共生成{len(self.chapters)}个章节",
                                {
                                    "chapter_count": len(self.chapters),
                                    "chapter_titles": [ch.title for ch in self.chapters]
                                })
            
            # 步骤4: 要点生成
            self._update_progress("points_generation", "processing", 0, "开始生成各章节要点")
            
            await self._generate_all_points()
            
            # 统计要点数量
            total_level1_points = sum(len(ch.points) for ch in self.chapters)
            total_level2_points = sum(
                len(point.sub_points) if point.sub_points else 0 
                for ch in self.chapters 
                for point in ch.points
            )
            
            self._update_progress("points_generation", "completed", 100,
                                f"要点生成完成，共{total_level1_points}个一级要点，{total_level2_points}个二级要点",
                                {
                                    "level1_points": total_level1_points,
                                    "level2_points": total_level2_points
                                })
            
            # 步骤5: 结果组装
            self._update_progress("result_assembly", "processing", 0, "正在组装最终结果")
            
            result = CourseContent(
                title=self.course_title,
                chapters=self.chapters
            )
            
            self._update_progress("result_assembly", "completed", 100, "课程内容解析完成")
            
            return result
            
        except Exception as e:
            current_step = "content_analysis"  # 默认步骤
            self._update_progress(current_step, "failed", 0, f"解析过程失败: {str(e)}")
            raise
    
    def _preprocess_content(self, content: str) -> str:
        """预处理文本内容."""
        content = re.sub(r'\s+', ' ', content.strip())
        content = content.replace('\r\n', '\n').replace('\r', '\n')
        return content
    
    def _extract_course_title(self, content: str) -> str:
        """提取课程标题."""
        lines = content.split('\n')
        
        if lines:
            first_line = lines[0].strip()
            if len(first_line) < 100 and any(keyword in first_line for keyword in ["课程", "教程", "培训", "学习", "course", "tutorial"]):
                return first_line
        
        for line in lines[:5]:
            line = line.strip()
            if line and len(line) < 50 and any(keyword in line for keyword in ["课程", "教程", "培训"]):
                return line
        
        return "课程内容"
    
    async def _generate_chapters(self, content: str) -> List[CourseChapter]:
        """生成章节."""
        chapters = []
        lines = content.split('\n')
        current_chapter_lines = []
        current_chapter_title = ""
        
        for line in lines:
            line = line.strip()
            if not line:
                continue
            
            if self._is_chapter_title(line):
                if current_chapter_title and current_chapter_lines:
                    chapter = await self._create_chapter_skeleton(current_chapter_title, current_chapter_lines)
                    if chapter:
                        chapters.append(chapter)
                
                current_chapter_title = line
                current_chapter_lines = []
            else:
                current_chapter_lines.append(line)
        
        if current_chapter_title and current_chapter_lines:
            chapter = await self._create_chapter_skeleton(current_chapter_title, current_chapter_lines)
            if chapter:
                chapters.append(chapter)
        
        if not chapters:
            chapters = await self._create_default_chapters(content)
        
        return chapters
    
    async def _create_chapter_skeleton(self, title: str, content_lines: List[str]) -> CourseChapter:
        """创建章节骨架（不含要点）."""
        description = self._extract_chapter_description(content_lines)
        
        return CourseChapter(
            title=title,
            description=description,
            points=[]  # 稍后填充
        )
    
    async def _generate_all_points(self):
        """为所有章节生成要点."""
        for i, chapter in enumerate(self.chapters):
            self._update_progress("points_generation", "processing", 
                                int((i / len(self.chapters)) * 100),
                                f"正在生成第{i+1}章节要点: {chapter.title}")
            
            # 获取章节的原始内容
            chapter_content = await self._get_chapter_content(chapter.title)
            
            # 生成一级要点
            level1_points = await self._extract_level1_points(chapter_content)
            
            # 为每个一级要点生成二级要点
            for point in level1_points:
                point.sub_points = await self._extract_level2_points(point, chapter_content)
            
            chapter.points = level1_points
            
            # 统计当前章节要点数量
            level2_count = sum(len(p.sub_points) if p.sub_points else 0 for p in level1_points)
            
            self._update_progress("points_generation", "processing",
                                int(((i + 1) / len(self.chapters)) * 100),
                                f"第{i+1}章节要点生成完成: {len(level1_points)}个一级要点，{level2_count}个二级要点")
    
    async def _get_chapter_content(self, chapter_title: str) -> List[str]:
        """获取章节的原始内容."""
        lines = self.parsed_content.split('\n')
        chapter_lines = []
        in_chapter = False
        
        for line in lines:
            line = line.strip()
            if not line:
                continue
                
            if self._is_chapter_title(line):
                if in_chapter:
                    break  # 到了下一章节
                if chapter_title in line:
                    in_chapter = True
                    continue
            elif in_chapter:
                chapter_lines.append(line)
        
        return chapter_lines
    
    async def _extract_level1_points(self, content_lines: List[str]) -> List[CoursePoint]:
        """提取一级要点."""
        points = []
        current_point = None
        current_content = []
        
        for line in content_lines:
            if self._is_point_title(line):
                if current_point:
                    point = self._create_point(current_point, current_content, level=1)
                    if point:
                        points.append(point)
                
                current_point = line
                current_content = []
            else:
                current_content.append(line)
        
        if current_point:
            point = self._create_point(current_point, current_content, level=1)
            if point:
                points.append(point)
        
        if not points:
            points = self._generate_auto_points(content_lines, level=1)
        
        return points
    
    async def _extract_level2_points(self, parent_point: CoursePoint, chapter_content: List[str]) -> List[CoursePoint]:
        """为一级要点提取二级要点."""
        # 简化逻辑：基于父要点的内容生成子要点
        sub_points = []
        
        # 如果父要点描述较长，可以拆分为子要点
        if len(parent_point.description) > 100:
            # 按句号分割生成子要点
            sentences = parent_point.description.split('。')
            for i, sentence in enumerate(sentences[:3], 1):  # 最多3个子要点
                if len(sentence.strip()) > 10:
                    sub_point = CoursePoint(
                        title=f"{parent_point.title}-{i}",
                        description=sentence.strip(),
                        level=2
                    )
                    sub_points.append(sub_point)
        
        return sub_points
    
    def _is_chapter_title(self, line: str) -> bool:
        """判断是否为章节标题."""
        if re.match(r'^\d+\.?\s*', line):
            return True
        
        for keyword in self.chapter_keywords:
            if keyword in line:
                return True
        
        if re.match(r'^第[一二三四五六七八九十\d]+[章节单元]', line):
            return True
        
        return False
    
    def _is_point_title(self, line: str) -> bool:
        """判断是否为要点标题."""
        if re.match(r'^[\d\w]+\.?\s+', line):
            return True
        
        for keyword in self.point_keywords:
            if keyword in line:
                return True
        
        if re.match(r'^[•·▪▫○●]\s*', line):
            return True
        
        return False
    
    def _create_point(self, title: str, content_lines: List[str], level: int = 1) -> CoursePoint:
        """创建要点对象."""
        title = re.sub(r'^[\d\w•·▪▫○●]+\.?\s*', '', title).strip()
        description = self._generate_point_description(title, content_lines)
        
        return CoursePoint(
            title=title,
            description=description,
            level=level
        )
    
    def _generate_point_description(self, title: str, content_lines: List[str]) -> str:
        """生成要点描述."""
        if content_lines:
            description = content_lines[0].strip()
            return description[:100] if description else f"{title}的相关内容"
        
        return f"关于{title}的要点内容"
    
    def _generate_auto_points(self, content_lines: List[str], level: int = 1) -> List[CoursePoint]:
        """自动生成要点."""
        points = []
        
        paragraphs = []
        current_paragraph = []
        
        for line in content_lines:
            if line.strip():
                current_paragraph.append(line)
            else:
                if current_paragraph:
                    paragraphs.append(' '.join(current_paragraph))
                    current_paragraph = []
        
        if current_paragraph:
            paragraphs.append(' '.join(current_paragraph))
        
        for i, paragraph in enumerate(paragraphs[:5], 1):
            if len(paragraph) > 20:
                title = f"要点{i}"
                description = paragraph[:100] + "..." if len(paragraph) > 100 else paragraph
                
                points.append(CoursePoint(
                    title=title,
                    description=description,
                    level=level
                ))
        
        return points
    
    def _extract_chapter_description(self, content_lines: List[str]) -> str:
        """提取章节描述."""
        description_lines = []
        for line in content_lines[:3]:
            if not self._is_point_title(line) and len(line) > 10:
                description_lines.append(line)
        
        description = ' '.join(description_lines)
        return description[:200] if description else "本章节内容"
    
    async def _create_default_chapters(self, content: str) -> List[CourseChapter]:
        """创建默认章节."""
        lines = [line.strip() for line in content.split('\n') if line.strip()]
        
        chapter = CourseChapter(
            title="主要内容",
            description="课程核心内容概述",
            points=[]  # 稍后填充
        )
        
        return [chapter]